/*
 * PthreadEpoll.h
 *
 *  Created on: 2013-5-15
 *      Author: wangrongming
 */

#ifndef PTHREADEPOLL_H_
#define PTHREADEPOLL_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <iostream>
#include <vector>
#include <queue>
#include <map>
#include <string>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <fcntl.h>
#include <syslog.h>
#include <regex.h>
#include <pthread.h>
#include <errno.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>



//#include "common/socketpkg/socketpkg.h"
//#include "common/socketpkg/boss_sockfun.h"

#include "CTraceLog.h"

//#define INT_THREADS_COUNT  1
//#define OUT_THREADS_COUNT  2

extern int  INT_THREADS_COUNT;
extern int  OUT_THREADS_COUNT;

#define MAX_EPOLL_SIZE 1024
#define EPOLL_EVENT_QUEUE 512
#define BUFFER_SIZE     1024
#define EventData_SIZE  512

typedef struct epoll_event  epoll_event_type;
typedef void(* func_type)(void* );

typedef int (* func_type_argv2)( void *, int  );

typedef int  socket_t;


typedef struct dealfunc_block_queue_param
{
	void * func_send;
	void * func_recv;

	void * epoll_sockdata_queue;

	void * epoll_event_queue_recv;
	void * epoll_event_queue_send;

}dealfunc_block_queue_param_t;


typedef struct _tagSockInfo
{
	socket_t fd;
	unsigned int    fd_events;

	in_addr_t    	nIPAddr;
	unsigned short  nPort;

	_tagSockInfo()
	{
		memset(this, 0x00, sizeof(_tagSockInfo));
	}

}SockInfo_t;

typedef std::queue<SockInfo_t*>  SockClientQueueType;


typedef struct _tagSockData
{

	int fd;
	unsigned int    fd_events;

	in_addr_t    	nIPAddr;
	unsigned short  nPort;

	//SockInfo_t      sockinfo;

	//unsigned int    events_index;
	unsigned int    events_index_in;
	unsigned int    events_index_out;

	unsigned long   nSeqNum;


	bool bUseBuff;
	bool bUseFunc;
	
	int nEvtRefNum;
	int nEvtUseStat;
	///is set data over
	bool bDoitBuff;
	///is Client Closed
	bool bClientClosed;

	void * func_send;
	void * func_recv;

	void * pSendBuff;
	void * pRecvBuff;

	int nSendSize;
	int nRecvSize;

	char szEventBuff[EventData_SIZE];

	struct timeval tmval;

	_tagSockData()
	{
		memset(this, 0x00, sizeof(_tagSockData));
		nRecvSize = sizeof(szEventBuff);
		nSendSize = sizeof(szEventBuff);

		fd = -1;
		nEvtUseStat   = 0x00;
		tmval.tv_sec  = 0x00;
		tmval.tv_usec = 0x00;

	}

	void clear()
	{
		memset(this, 0x00, sizeof(_tagSockData));
		nRecvSize = sizeof(szEventBuff);
		nSendSize = sizeof(szEventBuff);

		fd = -1;
		nEvtUseStat   = 0x00;
		tmval.tv_sec  = 0x00;
		tmval.tv_usec = 0x00;



	}

}SockData_t;

typedef std::queue<SockData_t*>  SockData_Queue_Type;

class SockDataQueueType
{
public:
	SockDataQueueType(pthread_mutex_t * pMutex,  pthread_cond_t * m_pCond);
	~SockDataQueueType();

public:

	size_t size();
	size_t size_new();
	bool empty();

	void clear();
	void show();

	SockData_t *  front2back(void);

	SockData_t * nAlloc_one(void);
	void nFree_one(SockData_t * pData);

	void lock(void);
	void unlock(void);

private:

	SockData_t * pop_front();
	int push_back(SockData_t * pData);


private:

	pthread_mutex_t * m_pMutex;
	pthread_cond_t  * m_pCond;

	SockData_Queue_Type m_SockDataQueue;
	SockData_Queue_Type m_SockDataQueueNew;
};

class block_queue_mamager
{
public:
	block_queue_mamager(pthread_mutex_t * pmutex_d, pthread_cond_t  * pcond_d ,
			            pthread_mutex_t * pmutex,   pthread_cond_t  * pcond ,  bool bSend = true);

	block_queue_mamager( pthread_mutex_t * pmutex, pthread_cond_t  * pcond , bool bSend = false);

	~block_queue_mamager();

public:

	int size();
	bool empty();
	void clear();

	void lock(void);
	void unlock(void);

	epoll_event_type front2back(void);

	epoll_event_type  nUsed_one(void);
	void nFeed_one(epoll_event_type &  pEvent);

	int nCondSignal(void);
private:

	epoll_event_type  pop_front();
	int push_back(epoll_event_type & pEvent);

public:


	unsigned int m_index_pop;
	unsigned int m_index_push;
	unsigned int m_index_new;
	bool m_bSend;

private:
	std::queue<epoll_event_type>  m_queue_std;

	//SockData_Queue_Type          m_SockDataQueueOt;

	pthread_mutex_t * m_mutex;
	pthread_cond_t  * m_cond;

	pthread_mutex_t * m_mutex_d;
	pthread_cond_t  * m_cond_d;

};

typedef void (*sighandler_t)(int);

void vSetSignalHander(void);

void vSignalHander(int nSignalNum);

char* strsub (char *instr, unsigned start, unsigned end);
int   setnonblocking(int sockfd);

//void SockSvr_Recv(void * sockfd);
//void SockSvr_Send(void * sockfd);
//
//void SockSvr_Send_Buff(char * szBuff, void* sockfd);

char * nGetHttpResp(void);

int SockSvr_Recv_Argv2(void * param, int nParamType);
int SockSvr_Send_Argv2(void * param, int nParamType);

int SockSvr_Recv_Argv4(char * szBuff, int nSendLength, void * param, int nParamType);
int SockSvr_Send_Argv4(char * szBuff, int nSendLength, void * param, int nParamType);


int init_SockSvr(int port);

//int init_threads_event();

int init_threads_event();
int init_threads_in_evt();
int init_threads_ot_evt();

//void * vFuncDealBlockQueue(void * arg_bqp);
//void * vFuncBothBlockQueue(void * arg_bqp);
//void * vFuncOutBlockQueue(void * arg_bqp);

void * vFuncRecvBlockQueue(void * arg_bqp);
void * vFuncSendBlockQueue(void * arg_bqp);


char * addr_ntoa( in_addr_t * pAddr, char * szAddress = NULL, int nAddrlen = 0x00);
//////////////////
int nHandlerEvent(void * event);
int nHandlerInEvent(void * event);
int nHandlerOtEvent(void * event);

int nCleanSockFreeQueue(void);
int nCheckSockEventQueue(void);

int  nGetDiffTimeVal(struct timeval * ptmval , int & nsecond, int & nMicSec);
void recv_interrupt_handler(int sig);
void send_interrupt_handler(int sig);

//int Deal_SockSvr_RecvData(const char * szRecvData, int nRecvLength);

int Deal_SockSvr_RecvData_RespArr(
									const char * szRecvData,
									int nRecvLength,
									SockData_t *  pSockData);


int CreateWorker(int nWorker);

int _test_one__main(int argc, char **argv);
//int _test_tow__main(int argc, char **argv);
int _test_tre__main(int argc, char **argv);


#endif /* PTHREADEPOLL_H_ */
